﻿
using System;
namespace PaceR.Core.EntityStorage
{
    /// <summary>
    /// Abstract class for storing an entity for later use
    /// </summary>
    public abstract class EntityStore
    {
        /// <summary>
        /// Get a stored entity
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <returns></returns>
        public virtual T GetEntity<T>()
        {
            return GetEntity<T>(null);
        }
        /// <summary>
        /// Get a stored entity
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <param name="key">key of entity</param>
        /// <returns></returns>
        public virtual T GetEntity<T>(string key)
        {
            string storageKey = BuildKey(typeof(T), key);
            return (T)(GetEntity(storageKey) ?? default(T));
        }
        /// <summary>
        /// Get a stored entity
        /// </summary>
        /// <param name="storageKey">Constructed key of stored entity</param>
        /// <returns></returns>
        protected abstract object GetEntity(string storageKey);
        /// <summary>
        /// Save an entity in storage
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <param name="entity"></param>
        public virtual void SaveEntity<T>(T entity)
        {
            SaveEntity<T>(entity, null);
        }
        /// <summary>
        /// Save an entity in storage
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <param name="entity">entity to store</param>
        /// <param name="key">key of entity</param>
        public virtual void SaveEntity<T>(T entity, string key)
        {
            string storageKey = BuildKey(typeof(T), key);
            SaveEntity(storageKey, entity);
        }
        /// <summary>
        /// Save an entity in storage
        /// </summary>
        /// <param name="storageKey">Constructed key to save entity by</param>
        /// <param name="entity">entity to store</param>
        protected abstract void SaveEntity(string storageKey, object entity);
        /// <summary>
        /// Clear a stored entity
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        public virtual void ClearEntity<T>()
        {
            ClearEntity<T>(null);
        }
        /// <summary>
        /// Clear a stored entity
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <param name="key">key of entity</param>
        public virtual void ClearEntity<T>(string key)
        {
            string storageKey = BuildKey(typeof(T), key);
            ClearEntity(storageKey);
        }
        /// <summary>
        /// Clear a stored entity
        /// </summary>
        /// <param name="storageKey">Constructed key of stored entity</param>
        protected abstract void ClearEntity(string storageKey);
        /// <summary>
        /// Builds key with a passed in key string and type
        /// </summary>
        /// <param name="type"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected virtual string BuildKey(Type type, string key)
        {
            string storageKey = type.ToString();
            if (!string.IsNullOrEmpty(key))
                storageKey += key;
            return storageKey;
        }
    }
}
